package com.hx.juc.concurrent;

/**
 * @author jxlgcmh
 * @create 2019-05-26 21:32
 */

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 模拟大坏蛋和小小兵 主线程代表大坏蛋，新建n个小黄人，等待坏蛋下指令；
 * 大坏蛋下了指令，小黄人开始执行任务，执行完之前，坏蛋要一直等着。
 * 小小兵执行完任务，大坏蛋才能下发新的指令。
 *
 * @author Administrator
 */
public class CountdownLatchTest {

    public static void main(String[] args) {
        // 创建一个线程池（一个军队）
        ExecutorService service = Executors.newCachedThreadPool();
        // 坏蛋指令，默认为1，变为0时，执行命令
        final CountDownLatch cdOrder = new CountDownLatch(1);

        //小黄人数量
        final int soilder_count = 6;

        // n个小黄人，一个小黄人执行完任务，cdAnswer减1，n个小黄人执行完毕，cdAnswer为0
        final CountDownLatch cdAnswer = new CountDownLatch(soilder_count);

        for (int i = 0; i < soilder_count; i++) {

            Runnable runnable = () -> {
                //小黄人整装待发
                System.out.println("小黄人 : " + Thread.currentThread().getName() + " 准备好了.");

                try {
                    cdOrder.await();//等着坏蛋发出指令
                    //小黄人收到指令
                    System.out.println("小黄人 : " + Thread.currentThread().getName() + " 接受命令.");

                    Thread.sleep((long) (Math.random() * 10000));
                    //执行完毕，告诉大坏蛋。
                    System.out.println("小黄人 : " + Thread.currentThread().getName() + " 告诉大坏蛋，任务完成.");

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    //执行一个减少一次
                    cdAnswer.countDown();
                }

            };

            service.execute(runnable);// 往执行军队里加派小黄人
        }

        try {
            Thread.sleep((long) (Math.random() * 10000));
            System.out.println("After 10s.....");

            //马上就要下达指令啦！
            System.out.println("大坏蛋 : " + Thread.currentThread().getName() + " 将要下发指令.");

            //发布指令，等待他们执行完
            System.out.println("大坏蛋 : " + Thread.currentThread().getName() + " 发布指令了，快去执行，等你们消息");

            cdOrder.countDown();// 发送指令“小黄人出动！”

            cdAnswer.await(); // 大坏蛋等着小黄人回来

            //收到所有完成的反馈
            System.out.println("大坏蛋 : " + Thread.currentThread().getName() + " 任务都完成了，收到了所有的反馈.");

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        service.shutdown();// 整个军队撤回！
    }

}
